package main {
  import flash.display.*;
  import flash.events.*;
  import fl.events.*;
  import flash.text.*;
  import flash.ui.*;
  import flash.net.*;
  import flash.utils.*;
  import fl.controls.List;
  import api.DataProvider;
  
  /**
   * Data Accessor class
   * 
   * Interacts via Data Provider with VKontakte API 
   *
   */
  
  public class DataAccessor extends EventDispatcher {
    public static var INIT:String = "init";
    
    private const VAR_PLACES_FIRST:Number = 1296;
    private const MAX_PLACES_VARS: Number = 128;
    private const VARS_PER_REQUEST: Number = 32;
    
    private var _data_provider:DataProvider;
    private var _places:Array = new Array();
    private var _unused_vars:Array = new Array();
    private var _user_id:Number;
    
    public function get places():Array {
      return Utils.clone(_places); 
    }
    
    /**
     * Constructor
     * 
     */
    public function DataAccessor(viewer_id:Number, user_id:Number) {
      _data_provider = new DataProvider(49416, "SOME_SECRET_CODE", viewer_id, false);
      _user_id = user_id;
      init();
    }
    
    /**
     * Initiates object and sends request for getting places vars
     * 
     */
    public function init() {
      _data_provider.setup({onError:function(error) {
        trace(error);
      }});
      
      for (var i:Number = 0; i < MAX_PLACES_VARS; i++) {
        _unused_vars.push(VAR_PLACES_FIRST + i);
      }
      
      receiveAllPlaces(0);
    }
    
    public function receiveAllPlaces(var_offset:Number) {
      if (var_offset > MAX_PLACES_VARS - 1) return;
      var vars_count:Number = Math.min(VARS_PER_REQUEST, MAX_PLACES_VARS - var_offset);
      
      _data_provider.request(DataProvider.GET_VARIABLES, {
        params:{user_id: _user_id, key:VAR_PLACES_FIRST + var_offset, count: vars_count},
        onComplete:onVarsReceive
      });
      var_offset += vars_count;
      setTimeout(receiveAllPlaces, 800, var_offset);
    }
    
    /**
     * Event handler on places vars receive
     * 
     */
    public function onVarsReceive(result:Object) {
      var initiated:Boolean = false;
      for (var i:String in result) {
        var key:Number = parseInt(result[i].var_info.key);
        var place:Array = result[i].var_info.value.split("|");
        if (key == VAR_PLACES_FIRST + MAX_PLACES_VARS - 1) {
          initiated = true;
        }
        if (place.length != 3) continue;
        _places.push({
          key: key,
          x: place[0],
          y: place[1],
          title: place[2]
        });
        // remove key from the list of unused keys
        if (_unused_vars.indexOf(key) >= 0) {
          _unused_vars.splice(_unused_vars.indexOf(key), 1);
        }
      }
      if (initiated) {
        dispatchEvent(new Event(INIT));
      }
    }
    
    
    /**
     * Adds place to vars
     * 
     */
    public function addPlace(x:Number, y:Number, title:String) {
      var key: Number = _unused_vars.splice(0, 1);
      if (isNaN(key)) return false;
      _data_provider.request(DataProvider.PUT_VARIABLE, {
        params:{user_id:_user_id, key:key, value: [x,y,title.replace("|","")].join("|")}
      });
      return key;
    }
    
    /**
     * Updates place info
     * 
     */
    public function editPlace(key:Number, x:Number, y:Number, title:String) {
      if (_unused_vars.indexOf(key) != -1) {
        return false;
      }
      _data_provider.request(DataProvider.PUT_VARIABLE, {
        params:{user_id:_user_id, key:key, value: [x,y,title.replace("|","")].join("|")}
      });
    }
    
    /**
     * Removes place by key
     * 
     */
    public function removePlace(key:Number) {
      _unused_vars.push(key);
      _data_provider.request(DataProvider.PUT_VARIABLE, {
        params:{key:key, value: ""}
      });
    }
    
    /**
     * Returns first unused API var
     * 
     */
    public function getUnusedVar() {
      if (_unused_vars.length == 0) return false;
      return _unused_vars[0];
    }
    
  }
}